package com.yf.service.manage.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exception.ServiceException;
import com.yf.mapper.ai.AiConversationToolBindingMapper;
import com.yf.mapper.ai.AiToolMapper;
import com.yf.model.ai.entity.AiConversationToolBinding;
import com.yf.model.ai.entity.AiTool;
import com.yf.result.ResultCode;
import com.yf.service.manage.IAiConversationToolBindingService;
import com.yf.utils.BindingUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * AI 会话工具绑定表-AiConversationToolBindingServiceImpl
 *
 * @author: YiFei
 * @since : 2025年7月5日 00:49:24
 */
@Service("aiConversationToolBindingService")
@RequiredArgsConstructor
public class AiConversationToolBindingServiceImpl extends ServiceImpl<AiConversationToolBindingMapper, AiConversationToolBinding> implements IAiConversationToolBindingService {

    private final AiToolMapper aiToolMapper;

    /**
     * 获取会话绑定的工具列表
     *
     * @param conversationId 会话ID
     * @return 绑定的工具列表
     */
    @Override
    public List<AiTool> getToolsByConversationId(Long conversationId) {
        // 查询会话绑定的工具列表
        List<AiConversationToolBinding> list = this.lambdaQuery()
                .eq(AiConversationToolBinding::getConversationId, conversationId)
                .list();
        // 如果没有绑定工具，返回空列表
        if (list.isEmpty()) {
            return Collections.emptyList();
        }
        // 查询工具集合
        return aiToolMapper.selectBatchIds(
                list.stream()
                        .map(AiConversationToolBinding::getToolId)
                        .collect(Collectors.toSet())
        );
    }

    /**
     * 绑定工具到会话 ( 单个会话最多绑定 100 个 tools )
     *
     * @param conversationId 会话ID
     * @param toolIds        工具ID 集合
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean bindToolToConversation(Long conversationId, Set<Integer> toolIds) {
        if (toolIds.size() > 100) {
            throw new ServiceException(ResultCode.AI_TOO_MANY_REQUESTS);
        }

        // 绑定新的工具 ， 解绑旧的工具
        return BindingUtil.bindEntities(
                conversationId,
                toolIds,
                (id) -> this.lambdaQuery()
                        .eq(AiConversationToolBinding::getConversationId, id)
                        .list().stream().map(AiConversationToolBinding::getToolId).collect(Collectors.toSet()),
                (id, bindIds) -> this.saveBatch(
                        bindIds.stream()
                                .map(toolId -> AiConversationToolBinding.builder()
                                        .conversationId(id)
                                        .toolId(toolId)
                                        .build())
                                .collect(Collectors.toList())
                ),
                (id, unBindIds) -> this.lambdaUpdate()
                        .eq(AiConversationToolBinding::getConversationId, id)
                        .in(AiConversationToolBinding::getToolId, unBindIds)
                        .remove()
        );
    }
}
